package uk.co.richardwkirk.parkrun.news;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import uk.co.richardwkirk.parkrun.data.ParkrunDataLoadException;
import uk.co.richardwkirk.parkrun.web.ParkrunPageLoader;
import uk.co.richardwkirk.parkrun.web.ParkrunWebException;

public class NewsFeed implements Iterable<NewsItem> {

	List<NewsItem> newsItems = null;
	
	String title = null;
	String link = null;
	
	public NewsFeed() {
		newsItems = new LinkedList<NewsItem>();
	}
	
	/**
	 * Create a NewsFeed object containing the news items from the RSS feed
	 * accessed by the provided Url.
	 * 
	 * @param url
	 * @return
	 * @throws ParkrunWebException
	 * @throws ParkrunDataLoadException 
	 */
	public static NewsFeed loadNewsFeed(String rssUrl) throws ParkrunDataLoadException {
		// Load the RSS feed for the news 
		ParkrunPageLoader pageLoader = new ParkrunPageLoader();
		InputStreamReader feedInput = pageLoader.loadStreamReader(rssUrl);
		
		// Populate a news feed item from the stream
		NewsFeed newsFeed = new NewsFeed();
		newsFeed.populate(feedInput);
		return newsFeed;
	}

	public static String loadNewsFeedString(String rssUrl) throws ParkrunDataLoadException {
		// Load the RSS feed for the news 
		ParkrunPageLoader pageLoader = new ParkrunPageLoader();
		return pageLoader.load(rssUrl);
	}	
	

	/**
	 * Populate the current news feed object using the data on the 
	 * input stream provided.
	 * 
	 * @param feedInput
	 * @throws ParkrunWebException
	 */
	private void populate(InputStreamReader feedInput) throws ParkrunDataLoadException {
    	try {  		
        	// Parse the RSS content using a SAX parser
        	SAXParserFactory spf = SAXParserFactory.newInstance();
    		SAXParser sp = spf.newSAXParser();
    		XMLReader xr = sp.getXMLReader();
     
    		// SAX parser events are handled by a news feed handler 
    		NewsFeedHandler rh = new NewsFeedHandler(this);
       		xr.setContentHandler(rh);
    		xr.parse(new InputSource(feedInput));
    	}
    	catch (SAXException e) {
    		throw new ParkrunDataLoadException("Could not parser RSS news feed from parkrun website.", e);
    	} 
    	catch (IOException e) {
    		throw new ParkrunDataLoadException("Could not read input data from parkrun website.", e);
		} 
    	catch (ParserConfigurationException e) {
    		throw new ParkrunDataLoadException("RSS feed parser not configured correctly.", e);
		}
	}

	public NewsItem getItem(int i) {
		return newsItems.get(i);
	}

	public String getTitle() {
		return title;
	}

	public String getLink() {
		return link;
	}
	
	public void setTitle(String string) {
		title = string;
	}
	
	public void setLink(String string) {
		link = string;
	}

	public int countNewsItems() {
		return newsItems.size();
	}

	public void addItem(NewsItem currentItem) {
		newsItems.add(currentItem);
	}

	@Override
	public Iterator<NewsItem> iterator() {
		return newsItems.iterator();
	}
	
}
